﻿using BaseData.Domain;
using BaseData.ErrorCode;
using BaseData.Infrastructure.Depart;
using BaseData.Infrastructure.DTO;
using BaseData.Infrastructure.Metting;
using BaseData.Infrastructure.User;
using BaseData.ReadAPI.Applications.Commands.Role;
using BaseData.ReadAPI.Applications.Commands.User;
using BaseData.ReadAPI.DTO;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace BaseData.ReadAPI.Controllers
{
    /// <summary>
    /// 基础读控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]
    [ApiExplorerSettings(GroupName = "Base")]
    public class BaseController : ControllerBase
    {
        private readonly IMediator mediator;
        private readonly IMettingService metSer;
        private readonly IUserService userService;
        private readonly IConfiguration configuration;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mediator"></param>
        /// <param name="metSer"></param>
        /// <param name="userService"></param>
        /// <param name="configuration"></param>
        public BaseController(IMediator mediator,IMettingService metSer,IUserService userService,IConfiguration configuration)
        {
            this.mediator = mediator;
            this.metSer = metSer;
            this.userService = userService;
            this.configuration = configuration;
        }
        

        #region 用户角色权限
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="account">账号</param>
        /// <param name="pwd">密码</param>
        /// <returns>返回登录数据</returns>
        [HttpGet]
        [AllowAnonymous]
        public async Task<APIResult<UserRoleDto>> Login(string account,string pwd)
        {
            LoginCommand cmd = new LoginCommand
            {
                accountname = account,
                pwd = pwd
            };
            var res = await mediator.Send(cmd);
            if(res!=null)
            {
                res.Data.Token = GetToken(res.Data);
            }
            return res;
        }
        /// <summary>
        /// 生成Token
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]
        public string GetToken(UserRoleDto dto)
        {
            try
            {
                //Header包含类型，签名算法选择
                var signingAlogrithm = SecurityAlgorithms.HmacSha256;//选择签名算法HmacSha256 是一种基于哈希的消息认证码，结合了 SHA - 256 哈希算法用于确保 JWT 的完整性和真实性。
                //声明（负载信息定义）
                IEnumerable<Claim> claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name,dto.UserName),
                    new Claim(ClaimTypes.Role,dto.RoleName)
                };
                //对私钥的处理转换为字节
                var secretByte = Encoding.UTF8.GetBytes(configuration["AuthenticationDemo:SecretKey"]);
                var signKey =  new SymmetricSecurityKey(secretByte);//创建一个对称安全密钥

                //签名创建凭证使用之前创建的对称安全密钥和签名算法创建签名凭证，用于生成 JWT 的签名
                var signingcredentials = new SigningCredentials(signKey, signingAlogrithm);

                //JWT 令牌生成
                var token = new JwtSecurityToken(
                    issuer: configuration["AuthenticationDemo:Issuer"],//令牌的发布者，从配置中获取。
                    audience: configuration["AuthenticationDemo:Audience"],//令牌的接收者，从配置中获取。
                    claims: claims,//之前定义的负载信息
                    notBefore: DateTime.UtcNow,//令牌的发布时间，设置为当前时间。
                    expires: DateTime.UtcNow.AddHours(8),//令牌的过期时间，设置为当前时间加上 30 分钟。
                    signingCredentials: signingcredentials//之前创建的签名凭证。
                );
                //令牌字符串生成【使用 JwtSecurityTokenHandler 类将 JwtSecurityToken 实例转换为字符串形式的 JWT 令牌，并将其返回】
                var TokenStr = new JwtSecurityTokenHandler().WriteToken(token);
                return TokenStr;
            }
            catch (Exception)
            {

                throw;
            }
        }
        /// <summary>
        /// 添加角色
        /// </summary>
        /// <param name="roles"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<APIResult<int>> AddRole(Roles roles)
        {
            AddRoleCommand cmd = new AddRoleCommand
            {
                Data = roles
            };
            return await mediator.Send(cmd);
        }
        /// <summary>
        /// 显示用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<List<Users>>> GetUser()
        {
            var res = await userService.GetUser();
            return new APIResult<List<Users>>
            {
                Code = CodeEnum.Success,
                Message = "显示用户信息",
                Data = res
            };
        }
        /// <summary>
        /// 分页显示用户信息
        /// </summary>
        /// <param name="index">页码</param>
        /// <param name="size">页容量</param>
        /// <param name="userId">用户编号</param>
        /// <param name="level">会员等级</param>
        /// <param name="userTitle">标签</param>
        /// <param name="channel">渠道</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<PaggingResult<List<Users>>>> GetUsers(int index, int size, long? userId, string? level, string? userTitle, string? channel)
        {
            var res = await userService.GetUsers(index, size, userId, level, userTitle, channel);
            return new APIResult<PaggingResult<List<Users>>>
            {
                Code = CodeEnum.Success,
                Message = "分页显示用户信息成功",
                Data = res,
            };
        }
        /// <summary>
        /// 软删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<APIResult<int>> DelUser(int id)
        {
            var res = await userService.UserDel(id);
            return new APIResult<int>
            {
                Code = CodeEnum.Success,
                Message = "软删除成功",
                Data = res
            };
        }
        /// <summary>
        /// 添加用户角色
        /// </summary>
        /// <param name="user"></param>
        /// <param name="rolelist"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<APIResult<int>> AddUserRole(Users user,string rolelist)
        {
            var res = rolelist.Split(',').Select(x=>Convert.ToInt32(x)).ToList();
            await userService.AddUserRole(user,res);
            return new APIResult<int>
            {
                Code = CodeEnum.Success,
                Message = "添加用户角色成功",
                Data = 1
            };
        }
        /// <summary>
        /// 显示角色信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<List<Roles>>> GetRoles()
        {
            var res = await userService.GetRoles();
            return new APIResult<List<Roles>>
            {
                Code = CodeEnum.Success,
                Message = "显示角色信息成功",
                Data = res
            };
        }
        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="users"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<APIResult<int>> UpdUser(Users users)
        {
            var res = await userService.UpdUser(users);
            return new APIResult<int>
            {
                Code = CodeEnum.Success,
                Message = "更新用户信息成功",
                Data = res
            };
        }
        /// <summary>
        /// 根据用户编号显示角色信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<APIResult<List<int>>> GetRole(int userId)
        {
            var res = await userService.GetUsersRoles(userId);
            return new APIResult<List<int>>
            {
                Code = CodeEnum.Success,
                Message = "根据用户编号显示角色信息成功",
                Data = res
            };
        }
        #endregion

       

        

    }
}
